package dongze.com.ckdj.map;

import android.util.Pair;

import com.google.gson.JsonObject;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.inject.Inject;

import dongze.com.ckdj.adapter.ListItem;
import dongze.com.ckdj.adapter.TypedListItem;
import dongze.com.ckdj.dagger.component.AppComponent;
import dongze.com.ckdj.dagger.component.ServiceComponent;
import dongze.com.ckdj.data.DataLayer;
import dongze.com.ckdj.data.entity.request.AddMassLossRecordRequestBody;
import dongze.com.ckdj.data.entity.request.AddVinMapRequestBody;
import dongze.com.ckdj.data.entity.request.EditMassLossRecordRequestBody;
import dongze.com.ckdj.data.entity.request.RecordRequestBody;
import dongze.com.ckdj.data.entity.request.UserRequestBody;
import dongze.com.ckdj.data.entity.response.BrandResponse;
import dongze.com.ckdj.data.entity.response.GetCheckInRecordResponse;
import dongze.com.ckdj.data.entity.response.GetLaneResponse;
import dongze.com.ckdj.data.entity.response.GetNamePlateTodayResponse;
import dongze.com.ckdj.data.entity.response.GetNamePlateWorkLoadResponse;
import dongze.com.ckdj.data.entity.response.GetParkingAreaResponse;
import dongze.com.ckdj.data.entity.response.GetVinMapResponse;
import dongze.com.ckdj.data.entity.response.InsepctionSectionRecord;
import dongze.com.ckdj.data.entity.response.InspectionSectionRecordDetailResponse;
import dongze.com.ckdj.data.entity.response.InspectionSectionResponse;
import dongze.com.ckdj.data.entity.response.NamePlate;
import dongze.com.ckdj.data.entity.response.OperationsResponse;
import dongze.com.ckdj.data.entity.response.QueryChildPointsResponse;
import dongze.com.ckdj.data.entity.response.QueryMassLossRecordsResponse;
import dongze.com.ckdj.data.entity.response.QueryMassLossResponse;
import dongze.com.ckdj.data.entity.response.QueryMassLossTypesResponse;
import dongze.com.ckdj.data.entity.response.QueryOtherPointsResponse;
import dongze.com.ckdj.data.entity.response.ResponseTemplate;
import dongze.com.ckdj.data.entity.response.UploadImageResponse;
import dongze.com.ckdj.data.entity.response.User;
import dongze.com.ckdj.data.entity.response.VehicleInformationDetail;
import dongze.com.ckdj.data.entity.response.VehicleNumberResponse;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Scheduler;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.observers.DisposableObserver;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Created by fanqwz on 2017/7/26.
 */

public class MapUtil {
    @Inject
    DataLayer dataLayer;
    @Inject
    Scheduler scheduler;
    Scheduler mainThread;
    private final CompositeDisposable disposables;


    public MapUtil(AppComponent appComponent) {
        disposables = new CompositeDisposable();

        if (appComponent != null) {
            appComponent.inject(this);
            mainThread = io.reactivex.android.schedulers.AndroidSchedulers.mainThread();
        }
    }

    public MapUtil(ServiceComponent appComponent) {
        disposables = new CompositeDisposable();
        if (appComponent != null) {
            appComponent.inject(this);
            mainThread = io.reactivex.android.schedulers.AndroidSchedulers.mainThread();
        }
    }

    public void dispose() {
        if (!disposables.isDisposed()) {
            disposables.clear();
        }
    }

    private void addDispose(Disposable disposable) {
        this.disposables.add(disposable);
    }

    private final <T> boolean checkResponse(Response<ResponseTemplate<T>> response, ObservableEmitter<T> e) {
        if (response.code() != 200 || response.body() == null) {
            e.onError(new Exception("网络请求失败：ret=" + response.code() + "," + response.raw().request()));
            return true;
        } else if (!"200".equals(response.body().getHeader().getReturnCode())) {
            e.onError(new Exception(response.body().getHeader().getReturnMsg(), new Exception("服务端返回异常：ret=" + response.body().getHeader().getReturnCode())));
            return true;
        }

        return false;
    }

    public void login(String name, String passwd, DisposableObserver<User> observable) {
        final UserRequestBody user = new UserRequestBody();
        user.setUserNo(name);
        user.setUserPwd(passwd);
        disposables.add(Observable.create(new ObservableOnSubscribe<User>() {
            @Override
            public void subscribe(final ObservableEmitter<User> e) throws Exception {
                dataLayer.login(user)
                        .enqueue(new Callback<ResponseTemplate<User>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<User>> call, Response<ResponseTemplate<User>> response) {
                                if (checkResponse(response, e)) {
                                    return;
                                }

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<User>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));
    }

    public void mapInformationItemAutoCompleteTextModel(String num, String brand, String voyage, DisposableObserver<List<Pair<String, String>>> observable) {
        String regEx = "[^a-zA-Z0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(num);
        num = m.replaceAll("").trim();
        num = num.substring(0, num.length() >= 17 ? 17 : num.length());

        final Call<ResponseTemplate<List<VehicleNumberResponse>>> call = dataLayer.getVehicleNumber(num, brand, voyage);
        disposables.add(Observable.create(new ObservableOnSubscribe<List<VehicleNumberResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<VehicleNumberResponse>> e) throws Exception {
                call.enqueue(new Callback<ResponseTemplate<List<VehicleNumberResponse>>>() {
                    @Override
                    public void onResponse(Call<ResponseTemplate<List<VehicleNumberResponse>>> call, Response<ResponseTemplate<List<VehicleNumberResponse>>> response) {
                        if (checkResponse(response, e)) {
                            return;
                        }

                        e.onNext(response.body().getBody());
                        e.onComplete();
                    }

                    @Override
                    public void onFailure(Call<ResponseTemplate<List<VehicleNumberResponse>>> call, Throwable t) {
                        e.onError(t);
                    }
                });
            }
        }).map(new Function<List<VehicleNumberResponse>, List<Pair<String, String>>>() {
            @Override
            public List<Pair<String, String>> apply(List<VehicleNumberResponse> vehicleNumberResponses) throws Exception {
                List<Pair<String, String>> entries = new ArrayList<>(vehicleNumberResponses.size());

                for (int i = 0; i < vehicleNumberResponses.size(); i++) {
                    Pair<String, String> p = new Pair<>(vehicleNumberResponses.get(i).getVin(), vehicleNumberResponses.get(i).getBrand_name());
                    entries.add(p);
                }

                return entries;
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void mapInformationItemAutoCompleteTextModelWithVehicleNumberResponse(String num, String brand, String voyage, DisposableObserver<List<VehicleNumberResponse>> observable) {
        String regEx = "[^a-zA-Z0-9]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(num);
        num = m.replaceAll("").trim();
        num = num.substring(0, num.length() >= 17 ? 17 : num.length());

        final Call<ResponseTemplate<List<VehicleNumberResponse>>> call = dataLayer.getVehicleNumber(num, brand, voyage);
        disposables.add(Observable.create(new ObservableOnSubscribe<List<VehicleNumberResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<VehicleNumberResponse>> e) throws Exception {
                call.enqueue(new Callback<ResponseTemplate<List<VehicleNumberResponse>>>() {
                    @Override
                    public void onResponse(Call<ResponseTemplate<List<VehicleNumberResponse>>> call, Response<ResponseTemplate<List<VehicleNumberResponse>>> response) {
                        if (checkResponse(response, e)) {
                            return;
                        }

                        e.onNext(response.body().getBody());
                        e.onComplete();
                    }

                    @Override
                    public void onFailure(Call<ResponseTemplate<List<VehicleNumberResponse>>> call, Throwable t) {
                        e.onError(t);
                    }
                });
            }
        }).subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }


    public void getVehicleDetail(String vehicleNumber, String nodeCode, DisposableObserver<VehicleInformationDetail> observable) {
        final Call<ResponseTemplate<VehicleInformationDetail>> call = dataLayer.getVehicleInfationDetail(vehicleNumber, nodeCode);
        disposables.add(Observable.create(new ObservableOnSubscribe<VehicleInformationDetail>() {
            @Override
            public void subscribe(final ObservableEmitter<VehicleInformationDetail> e) throws Exception {
                call.enqueue(new Callback<ResponseTemplate<VehicleInformationDetail>>() {
                    @Override
                    public void onResponse(Call<ResponseTemplate<VehicleInformationDetail>> call, Response<ResponseTemplate<VehicleInformationDetail>> response) {
                        if (checkResponse(response, e)) {
                            return;
                        }

                        e.onNext(response.body().getBody());
                        e.onComplete();
                    }

                    @Override
                    public void onFailure(Call<ResponseTemplate<VehicleInformationDetail>> call, Throwable t) {
                        e.onError(t);
                    }
                });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void getMassLossRecords(String vinNo, DisposableObserver<List<QueryMassLossRecordsResponse>> observable) {
        final Call<ResponseTemplate<List<QueryMassLossRecordsResponse>>> call = dataLayer.getMassLossRecords(vinNo);
        disposables.add(Observable.create(new ObservableOnSubscribe<List<QueryMassLossRecordsResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<QueryMassLossRecordsResponse>> e) throws Exception {
                call.enqueue(new Callback<ResponseTemplate<List<QueryMassLossRecordsResponse>>>() {
                    @Override
                    public void onResponse(Call<ResponseTemplate<List<QueryMassLossRecordsResponse>>> call, Response<ResponseTemplate<List<QueryMassLossRecordsResponse>>> response) {
                        if (checkResponse(response, e)) {
                            return;
                        }
                        e.onNext(response.body().getBody());
                        e.onComplete();
                    }

                    @Override
                    public void onFailure(Call<ResponseTemplate<List<QueryMassLossRecordsResponse>>> call, Throwable t) {
                        e.onError(t);
                    }
                });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));
    }

    public void addMassLossRecord(AddMassLossRecordRequestBody body, DisposableObserver<Long> observable) {
        final Call<ResponseTemplate<Long>> call = dataLayer.addMassLossRecord(body);
        disposables.add(Observable.create(new ObservableOnSubscribe<Long>() {
            @Override
            public void subscribe(final ObservableEmitter<Long> e) throws Exception {
                call.enqueue(new Callback<ResponseTemplate<Long>>() {
                    @Override
                    public void onResponse(Call<ResponseTemplate<Long>> call, Response<ResponseTemplate<Long>> response) {
                        if (checkResponse(response, e)) {
                            return;
                        }
                        e.onNext(response.body().getBody());
                        e.onComplete();
                    }

                    @Override
                    public void onFailure(Call<ResponseTemplate<Long>> call, Throwable t) {
                        e.onError(t);
                    }
                });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));


    }

    public void getMassLossTypes(String childId, DisposableObserver<List<QueryMassLossTypesResponse>> observer) {
        final Call<ResponseTemplate<List<QueryMassLossTypesResponse>>> call = dataLayer.getMassLossTypes(childId);
        disposables.add(Observable.create(new ObservableOnSubscribe<List<QueryMassLossTypesResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<QueryMassLossTypesResponse>> e) throws Exception {
                call.enqueue(new Callback<ResponseTemplate<List<QueryMassLossTypesResponse>>>() {
                    @Override
                    public void onResponse(Call<ResponseTemplate<List<QueryMassLossTypesResponse>>> call, Response<ResponseTemplate<List<QueryMassLossTypesResponse>>> response) {
                        if (checkResponse(response, e)) {
                            return;
                        }
                        e.onNext(response.body().getBody());
                        e.onComplete();
                    }

                    @Override
                    public void onFailure(Call<ResponseTemplate<List<QueryMassLossTypesResponse>>> call, Throwable t) {
                        e.onError(t);
                    }
                });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));

    }

    public void getOtherPoints(String type, String brandCode, DisposableObserver<List<QueryOtherPointsResponse>> observable) {
        final Call<ResponseTemplate<List<QueryOtherPointsResponse>>> call = dataLayer.getOtherPoints(type, brandCode);
        disposables.add(Observable.create(new ObservableOnSubscribe<List<QueryOtherPointsResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<QueryOtherPointsResponse>> e) throws Exception {
                call.enqueue(new Callback<ResponseTemplate<List<QueryOtherPointsResponse>>>() {
                    @Override
                    public void onResponse(Call<ResponseTemplate<List<QueryOtherPointsResponse>>> call, Response<ResponseTemplate<List<QueryOtherPointsResponse>>> response) {
                        if (checkResponse(response, e)) {
                            return;
                        }
                        e.onNext(response.body().getBody());
                        e.onComplete();
                    }

                    @Override
                    public void onFailure(Call<ResponseTemplate<List<QueryOtherPointsResponse>>> call, Throwable t) {
                        e.onError(t);
                    }
                });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));
    }

    public Observable<List<QueryChildPointsResponse>> getChildPoints(String parentId) {
        final Call<ResponseTemplate<List<QueryChildPointsResponse>>> call = dataLayer.getPoints(parentId);
        return Observable.create(new ObservableOnSubscribe<List<QueryChildPointsResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<QueryChildPointsResponse>> e) throws Exception {
                call.enqueue(new Callback<ResponseTemplate<List<QueryChildPointsResponse>>>() {
                    @Override
                    public void onResponse(Call<ResponseTemplate<List<QueryChildPointsResponse>>> call, Response<ResponseTemplate<List<QueryChildPointsResponse>>> response) {
                        if (checkResponse(response, e)) {
                            return;
                        }
                        e.onNext(response.body().getBody());
                        e.onComplete();
                    }

                    @Override
                    public void onFailure(Call<ResponseTemplate<List<QueryChildPointsResponse>>> call, Throwable t) {
                        e.onError(t);
                    }
                });
            }
        });
    }

    public void getOperations(String vehivleNumber, String nodeCode, DisposableObserver<List<TypedListItem>> observable) {
        final Call<ResponseTemplate<List<OperationsResponse>>> call = dataLayer.getOperations(vehivleNumber, nodeCode);
        disposables.add(Observable.create(new ObservableOnSubscribe<List<OperationsResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<OperationsResponse>> e) throws Exception {
                call.enqueue(new Callback<ResponseTemplate<List<OperationsResponse>>>() {
                    @Override
                    public void onResponse(Call<ResponseTemplate<List<OperationsResponse>>> call, Response<ResponseTemplate<List<OperationsResponse>>> response) {
                        if (checkResponse(response, e)) {
                            return;
                        }

                        e.onNext(response.body().getBody());
                        e.onComplete();
                    }

                    @Override
                    public void onFailure(Call<ResponseTemplate<List<OperationsResponse>>> call, Throwable t) {
                        e.onError(t);
                    }
                });

            }
        })
                .map(new Function<List<OperationsResponse>, List<TypedListItem>>() {
                    @Override
                    public List<TypedListItem> apply(List<OperationsResponse> operationsResponses) throws Exception {
                        List<TypedListItem> typedListItems = new ArrayList<>(operationsResponses.size());

                        for (int i = 0; i < operationsResponses.size(); i++) {
                            TypedListItem typedListItem = new TypedListItem();
                            typedListItem.setKey(operationsResponses.get(i).getProgram_name());
                            typedListItem.setType(TypedListItem.Type.getTypeFromData(operationsResponses.get(i).getProgram_type()));
                            typedListItem.setId(operationsResponses.get(i).getProgram_id());
                            typedListItem.setSort(operationsResponses.get(i).getSort());

                            if (operationsResponses.get(i).getProgram_type() == 1) {
                                List<TypedListItem.Option> options = new ArrayList<>(operationsResponses.get(i).getOptions().size());

                                for (int j = 0; j < operationsResponses.get(i).getOptions().size(); j++) {
                                    TypedListItem.Option option = new TypedListItem.Option();
                                    option.setDislayname(operationsResponses.get(i).getOptions().get(j).getOption_name());
                                    option.setValue(operationsResponses.get(i).getOptions().get(j).getOption_value());
                                    options.add(option);
                                }

                                typedListItem.setOptions(options);
                            }
                            typedListItems.add(typedListItem);
                        }

                        return typedListItems;
                    }
                })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void uploadImage(final File image, DisposableObserver<String> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<UploadImageResponse>() {
            @Override
            public void subscribe(final ObservableEmitter<UploadImageResponse> e) throws Exception {
                dataLayer.uploadImage(image)
                        .enqueue(new Callback<UploadImageResponse>() {
                            @Override
                            public void onResponse(Call<UploadImageResponse> call, Response<UploadImageResponse> response) {
                                if (response.code() != 200 || response.body() == null) {
                                    e.onError(new Exception("网络请求失败+" + call.request()));
                                    return;
                                }

                                e.onNext(response.body());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<UploadImageResponse> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .map(new Function<UploadImageResponse, String>() {
                    @Override
                    public String apply(UploadImageResponse s) throws Exception {
                        return s.getPath();
                    }
                })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void queryMassLossReason(final String reason, DisposableObserver<Pair<List<QueryMassLossResponse>, String[]>> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<QueryMassLossResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<QueryMassLossResponse>> e) throws Exception {
                dataLayer.queryMassLossReason(reason)
                        .enqueue(new Callback<ResponseTemplate<List<QueryMassLossResponse>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<QueryMassLossResponse>>> call, Response<ResponseTemplate<List<QueryMassLossResponse>>> response) {
                                if (checkResponse(response, e)) {
                                    return;
                                }

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<QueryMassLossResponse>>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .map(new Function<List<QueryMassLossResponse>, Pair<List<QueryMassLossResponse>, String[]>>() {
                    @Override
                    public Pair<List<QueryMassLossResponse>, String[]> apply(List<QueryMassLossResponse> queryMassLossResponses) throws Exception {
                        String[] list = new String[queryMassLossResponses.size()];

                        for (int i = 0; i < list.length; i++) {
                            list[i] = queryMassLossResponses.get(i).getDescription_cn() + " " + queryMassLossResponses.get(i).getDescription_en();
                        }
                        return new Pair<>(queryMassLossResponses, list);
                    }
                })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void addRecord(final RecordRequestBody body, DisposableObserver<String> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {
                dataLayer.addRecord(body)
                        .enqueue(new Callback<ResponseTemplate<String>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<String>> call, Response<ResponseTemplate<String>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<String>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void commitMassLossRecord(final AddMassLossRecordRequestBody body, DisposableObserver<Long> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<Long>() {
            @Override
            public void subscribe(final ObservableEmitter<Long> e) throws Exception {
                dataLayer.addMassLossRecord(body)
                        .enqueue(new Callback<ResponseTemplate<Long>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<Long>> call, Response<ResponseTemplate<Long>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<Long>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void updateMassLossImageRecord(final String id, final String imageID, final String image, final String user, DisposableObserver<String> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {
                dataLayer.updateMassLossImageRecord(id, imageID, image, user)
                        .enqueue(new Callback<ResponseTemplate<String>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<String>> call, Response<ResponseTemplate<String>> response) {
                                if (checkResponse(response, e)) {
                                    return;
                                }

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<String>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void updateMassLossImageRecord(final EditMassLossRecordRequestBody body, DisposableObserver<String> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {
                dataLayer.updateMassLossImageRecord(body)
                        .enqueue(new Callback<ResponseTemplate<String>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<String>> call, Response<ResponseTemplate<String>> response) {
                                if (checkResponse(response, e)) {
                                    return;
                                }

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<String>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void getInspectionSectionRecords(final String vin, final String nodeCode, DisposableObserver<List<Pair<String, String>>> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<InsepctionSectionRecord>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<InsepctionSectionRecord>> e) throws Exception {
                dataLayer.getInspectionSectionRecords(vin)
                        .enqueue(new Callback<ResponseTemplate<List<InsepctionSectionRecord>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<InsepctionSectionRecord>>> call, Response<ResponseTemplate<List<InsepctionSectionRecord>>> response) {
                                if (checkResponse(response, e)) {
                                    return;
                                }

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<InsepctionSectionRecord>>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .map(new Function<List<InsepctionSectionRecord>, List<Pair<String, String>>>() {
                    @Override
                    public List<Pair<String, String>> apply(List<InsepctionSectionRecord> insepctionSectionRecords) throws Exception {
                        List<Pair<String, String>> pairs = new ArrayList<Pair<String, String>>(insepctionSectionRecords.size());
                        Calendar todayStart = Calendar.getInstance();
                        todayStart.set(Calendar.HOUR, 0);
                        todayStart.set(Calendar.MINUTE, 0);
                        todayStart.set(Calendar.SECOND, 0);
                        todayStart.set(Calendar.MILLISECOND, 0);
                        Date today = todayStart.getTime();
                        for (InsepctionSectionRecord i :
                                insepctionSectionRecords) {
//                            if (nodeCode.equals(i.getNode_code())
//                                    && i.getCreate_time().after(today))
                            pairs.add(new Pair<>(
                                    i.getRecord_id(), i.getNode_name()
                                    + ":"
                                    + ("1".equals(i.getType()) ? "附件" : "车身")
                                    + ":"
                                    + i.getUser_name()
                                    + ":"
                                    + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(i.getCreate_time())));
                        }
                        return pairs;
                    }
                })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void getInspectionSectionRecordDetail(final String id, DisposableObserver<Pair<List<InspectionSectionRecordDetailResponse>, List<ListItem>>> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<InspectionSectionRecordDetailResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<InspectionSectionRecordDetailResponse>> e) throws Exception {
                dataLayer.getInspectionSectionRecordDetail(id)
                        .enqueue(new Callback<ResponseTemplate<List<InspectionSectionRecordDetailResponse>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<InspectionSectionRecordDetailResponse>>> call, Response<ResponseTemplate<List<InspectionSectionRecordDetailResponse>>> response) {
                                if (checkResponse(response, e)) {
                                    return;
                                }

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<InspectionSectionRecordDetailResponse>>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })

                .map(new Function<List<InspectionSectionRecordDetailResponse>, Pair<List<InspectionSectionRecordDetailResponse>, List<ListItem>>>() {
                    @Override
                    public Pair<List<InspectionSectionRecordDetailResponse>, List<ListItem>> apply(List<InspectionSectionRecordDetailResponse> inspectionSectionRecordDetailResponse) throws Exception {
                        List<ListItem> listItems = new ArrayList<>(inspectionSectionRecordDetailResponse.size());

                        for (int i = 0; i < inspectionSectionRecordDetailResponse.size(); i++) {
                            ListItem listItem = new ListItem();
                            listItem.setKey(inspectionSectionRecordDetailResponse.get(i).getProgram_name());
                            listItem.setValue(inspectionSectionRecordDetailResponse.get(i).getProgram_value());
                            listItems.add(listItem);
                        }

                        return new Pair<>(inspectionSectionRecordDetailResponse, listItems);
                    }
                })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void getNamePlate(final String vin, DisposableObserver<NamePlate> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<NamePlate>() {
            @Override
            public void subscribe(final ObservableEmitter<NamePlate> e) throws Exception {
                dataLayer.getNamePlate(vin)
                        .enqueue(new Callback<ResponseTemplate<NamePlate>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<NamePlate>> call, Response<ResponseTemplate<NamePlate>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<NamePlate>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void uploadNamePlate(final String vin, final String imgID, final String img, final String userNo, DisposableObserver<String> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {
                JsonObject jsonObject = new JsonObject();
                jsonObject.addProperty("vin", vin);
                jsonObject.addProperty("userNo", userNo);
                jsonObject.addProperty(imgID, img);
                dataLayer.upLoadNamePlate(jsonObject)
                        .enqueue(new Callback<ResponseTemplate<String>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<String>> call, Response<ResponseTemplate<String>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<String>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));
    }

    public void uploadNamePlate(final JsonObject jsonObject, DisposableObserver<String> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {
                dataLayer.upLoadNamePlate(jsonObject)
                        .enqueue(new Callback<ResponseTemplate<String>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<String>> call, Response<ResponseTemplate<String>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<String>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));
    }

    public void getBrands(final String isChecked, DisposableObserver<List<BrandResponse>> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<BrandResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<BrandResponse>> e) throws Exception {
                dataLayer.getBrands(isChecked)
                        .enqueue(new Callback<ResponseTemplate<List<BrandResponse>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<BrandResponse>>> call, Response<ResponseTemplate<List<BrandResponse>>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<BrandResponse>>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));

    }

    public void getInspectionSections(final String brand, DisposableObserver<List<InspectionSectionResponse>> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<InspectionSectionResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<InspectionSectionResponse>> e) throws Exception {
                dataLayer.getInspectionSections(brand)
                        .enqueue(new Callback<ResponseTemplate<List<InspectionSectionResponse>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<InspectionSectionResponse>>> call, Response<ResponseTemplate<List<InspectionSectionResponse>>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<InspectionSectionResponse>>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));
    }

    public void getNamePlateToday(final String userNo, DisposableObserver<GetNamePlateTodayResponse> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<GetNamePlateTodayResponse>() {
            @Override
            public void subscribe(final ObservableEmitter<GetNamePlateTodayResponse> e) throws Exception {
                dataLayer.getNamePlateToday(userNo)
                        .enqueue(new Callback<ResponseTemplate<GetNamePlateTodayResponse>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<GetNamePlateTodayResponse>> call, Response<ResponseTemplate<GetNamePlateTodayResponse>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<GetNamePlateTodayResponse>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void getVoyage(final String brandNo, DisposableObserver<List<String>> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<String>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<String>> e) throws Exception {
                dataLayer.getVoyage(brandNo)
                        .enqueue(new Callback<ResponseTemplate<List<String>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<String>>> call, Response<ResponseTemplate<List<String>>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<String>>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void getNamePlateWorkLoad(final String brandCode, final String voyage, DisposableObserver<GetNamePlateWorkLoadResponse> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<GetNamePlateWorkLoadResponse>() {
            @Override
            public void subscribe(final ObservableEmitter<GetNamePlateWorkLoadResponse> e) throws Exception {
                dataLayer.getNamePlateWorkLoad(brandCode, voyage)
                        .enqueue(new Callback<ResponseTemplate<GetNamePlateWorkLoadResponse>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<GetNamePlateWorkLoadResponse>> call, Response<ResponseTemplate<GetNamePlateWorkLoadResponse>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<GetNamePlateWorkLoadResponse>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void getCheckInOperationSelection(final String key, final String param, final String type, final String brandCode, DisposableObserver<List<String>> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<String>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<String>> e) throws Exception {
                dataLayer.getCheckInOperationSelection(key, param, type, brandCode)
                        .enqueue(new Callback<ResponseTemplate<List<String>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<String>>> call, Response<ResponseTemplate<List<String>>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<String>>> call, Throwable t) {

                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void getParkingArea(DisposableObserver<List<GetParkingAreaResponse>> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<GetParkingAreaResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<GetParkingAreaResponse>> e) throws Exception {
                dataLayer.getParkingArea()
                        .enqueue(new Callback<ResponseTemplate<List<GetParkingAreaResponse>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<GetParkingAreaResponse>>> call, Response<ResponseTemplate<List<GetParkingAreaResponse>>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<GetParkingAreaResponse>>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void getLane(final String areaID, DisposableObserver<List<GetLaneResponse>> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<GetLaneResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<GetLaneResponse>> e) throws Exception {
                dataLayer.getLane(areaID)
                        .enqueue(new Callback<ResponseTemplate<List<GetLaneResponse>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<GetLaneResponse>>> call, Response<ResponseTemplate<List<GetLaneResponse>>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<GetLaneResponse>>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void addVinMap(final List<AddVinMapRequestBody> body, DisposableObserver<String> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {
                dataLayer.addVinMap(body)
                        .enqueue(new Callback<ResponseTemplate<String>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<String>> call, Response<ResponseTemplate<String>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<String>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void getEnclosureCheckInRecord(final String nodeCode, final String brandCode, final String voyage, DisposableObserver<GetCheckInRecordResponse> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<GetCheckInRecordResponse>() {
            @Override
            public void subscribe(final ObservableEmitter<GetCheckInRecordResponse> e) throws Exception {
                dataLayer.getEnclosureCheckInRecord(nodeCode, brandCode, voyage)
                        .enqueue(new Callback<ResponseTemplate<GetCheckInRecordResponse>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<GetCheckInRecordResponse>> call, Response<ResponseTemplate<GetCheckInRecordResponse>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<GetCheckInRecordResponse>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void getOutLineCheckInRecord(final String nodeCode, final String brandCode, final String voyage, DisposableObserver<GetCheckInRecordResponse> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<GetCheckInRecordResponse>() {
            @Override
            public void subscribe(final ObservableEmitter<GetCheckInRecordResponse> e) throws Exception {
                dataLayer.getOutLineCheckInRecord(nodeCode, brandCode, voyage)
                        .enqueue(new Callback<ResponseTemplate<GetCheckInRecordResponse>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<GetCheckInRecordResponse>> call, Response<ResponseTemplate<GetCheckInRecordResponse>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<GetCheckInRecordResponse>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void modifyCheckInRecord(final String recordID, final String value, DisposableObserver<String> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {
                dataLayer.modifyCheckInRecord(recordID, value)
                        .enqueue(new Callback<ResponseTemplate<String>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<String>> call, Response<ResponseTemplate<String>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<String>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        }).subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void deleteMassLossRecord(final String recordID, DisposableObserver<String> observer) {
        disposables.add(Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {
                dataLayer.deleteMassLossRecord(recordID)
                        .enqueue(new Callback<ResponseTemplate<String>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<String>> call, Response<ResponseTemplate<String>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<String>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        }).subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observer));
    }

    public void upLoadRandomInspection(final JsonObject jsonObject, DisposableObserver<String> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {
                dataLayer.upLoadRandomInspection(jsonObject)
                        .enqueue(new Callback<ResponseTemplate<String>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<String>> call, Response<ResponseTemplate<String>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<String>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));
    }

    public void getMassLossPositionID(final JsonObject jsonObject, DisposableObserver<List<QueryChildPointsResponse>> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<QueryChildPointsResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<QueryChildPointsResponse>> e) throws Exception {
                dataLayer.getMassLossPositionID(jsonObject)
                        .enqueue(new Callback<ResponseTemplate<List<QueryChildPointsResponse>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<QueryChildPointsResponse>>> call, Response<ResponseTemplate<List<QueryChildPointsResponse>>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<QueryChildPointsResponse>>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));
    }

    public void getVinMap(final JsonObject jsonObject, DisposableObserver<List<GetVinMapResponse>> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<List<GetVinMapResponse>>() {
            @Override
            public void subscribe(final ObservableEmitter<List<GetVinMapResponse>> e) throws Exception {
                dataLayer.getVinMap(jsonObject)
                        .enqueue(new Callback<ResponseTemplate<List<GetVinMapResponse>>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<List<GetVinMapResponse>>> call, Response<ResponseTemplate<List<GetVinMapResponse>>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<List<GetVinMapResponse>>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));
    }

    public void martinCommitCheckInImage(final JsonObject jsonObject, DisposableObserver<String> observable) {
        disposables.add(Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(final ObservableEmitter<String> e) throws Exception {
                dataLayer.martinCommitCheckInImage(jsonObject)
                        .enqueue(new Callback<ResponseTemplate<String>>() {
                            @Override
                            public void onResponse(Call<ResponseTemplate<String>> call, Response<ResponseTemplate<String>> response) {
                                if (checkResponse(response, e))
                                    return;

                                e.onNext(response.body().getBody());
                                e.onComplete();
                            }

                            @Override
                            public void onFailure(Call<ResponseTemplate<String>> call, Throwable t) {
                                e.onError(t);
                            }
                        });
            }
        })
                .subscribeOn(scheduler)
                .observeOn(mainThread)
                .subscribeWith(observable));
    }
}